#include "renderwidget.h"
#include <QPainter>
#include <QDebug>
#include <QTime>

#include <assert.h>
#include <iostream>

RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent), Filter(), imageData(0), imageWidth(0), imageHeight(0) {
	setAttribute(Qt::WA_OpaquePaintEvent, true); // don't clear the area before the paintEvent
	setAttribute(Qt::WA_PaintOnScreen, true); // disable double buffering
	//setFixedSize(imageWidth, imageHeight);
	connect(this, SIGNAL(frameSizeChanged(int, int)), this, SLOT(onFrameSizeChanged(int, int)), Qt::QueuedConnection);
	time = frames = 0;
}

void RenderWidget::onFrameSizeChanged(int width, int height) {
	setFixedSize(width, height);
} 

void RenderWidget::updatePixmap(const IplImage* frame) {
	QTime t;
	t.start();
	//qDebug() << "Copying data";
	bool start = false;
	// check if the frame dimensions have changed
	if(frame->width != imageWidth || frame->height != imageHeight || frame->nChannels != num_channels) { 
		if(imageData) {
			delete[] imageData;
		}
		start = true;
		imageWidth = frame->width;
		imageHeight = frame->height;
		num_channels = frame->nChannels;
		emit(frameSizeChanged(imageWidth, imageHeight));
		imageData = new unsigned char[4*imageWidth*imageHeight];
		for(int i = 0; i < imageWidth*imageHeight; i++) {
			imageData[i*4+0] = 0xFF;
			imageData[i*4+1] = 0xFF;
			imageData[i*4+2] = 0xFF;
			imageData[i*4+3] = 0xFF;
		}
	}

	int pixels = imageWidth * imageHeight;
	uchar* src = (uchar*)(frame->imageData);
    uchar* srcEnd = src + (num_channels*pixels);
    uchar* dest = imageData;

    assert(dest != NULL);
    assert(src != NULL);
    do {
		memcpy(dest, src, num_channels);
		dest += 4;
		src += num_channels;
    } while(src < srcEnd);
	if(!start) {
		++frames;
		time += t.elapsed();
		//qDebug() << (double)time/frames;
	}
	//qDebug() << "Done Copying data";
}

void RenderWidget::processPoint(ImageState* state) {
	// copy the image to the local pixmap and update the display
	updatePixmap(state->frame);
	update();

	notifyListener(state);
	cvReleaseImage(&(state->frame));
}

void RenderWidget::paintEvent(QPaintEvent*) {
//	QTime time;
//	time.start(); 
	QPainter painter(this);
	if(imageData) {
//QPixmap temp;
	//	qDebug() << temp.loadFromData(imageData, imageWidth*imageHeight*4);
		//qDebug() << "loading...";
		QImage tImg(imageData, imageWidth, imageHeight, QImage::Format_RGB32);
		//qDebug() << "drawing...";
		painter.drawImage(QPoint(0,0), tImg);
		//qDebug() << "done drawing";
	}
	else {
		painter.setBrush(Qt::black);
		painter.drawRect(rect());
	}
//	qDebug() << time.elapsed();
}
